package com.small.nacos.config.server.service;

import com.small.nacos.config.server.model.CacheItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author zhoujin
 * @Date 2022/11/23 13:35
 */
public class ConfigCacheService {

    protected static final Logger LOGGER = LoggerFactory.getLogger(ConfigCacheService.class);

    private static final ConcurrentHashMap<String, CacheItem> CACHE = new ConcurrentHashMap<String, CacheItem>();


    public static CacheItem getContentCache(String groupKey) {
        return CACHE.get(groupKey);
    }

    /**
     * 获取读锁
     *
     * @param groupKey
     * @return
     */
    public static int tryReadLock(String groupKey) {
        CacheItem groupItem = CACHE.get(groupKey);
        int result = (null == groupItem) ? 0 : (groupItem.rwLock.tryReadLock() ? 1 : -1);
        if (result < 0) {
            LOGGER.warn("[read-lock] failed, {}, {}", result, groupKey);
        }
        return result;
    }

    /**
     * 释放读锁
     *
     * @param groupKey
     */
    public static void releaseReadLock(String groupKey) {
        CacheItem item = CACHE.get(groupKey);
        if (null != item) {
            item.rwLock.releaseReadLock();
        }
    }

    /**
     * 获取写锁
     *
     * @param groupKey
     * @return
     */
    static int tryWriteLock(String groupKey) {
        CacheItem groupItem = CACHE.get(groupKey);
        int result = (null == groupItem) ? 0 : (groupItem.rwLock.tryWriteLock() ? 1 : -1);
        if (result < 0) {
            LOGGER.warn("[write-lock] failed, {}, {}", result, groupKey);
        }
        return result;
    }

    /**
     * 释放写锁
     *
     * @param groupKey
     */
    static void releaseWriteLock(String groupKey) {
        CacheItem groupItem = CACHE.get(groupKey);
        if (null != groupItem) {
            groupItem.rwLock.releaseWriteLock();
        }
    }


    /**
     * 获取缓存
     *
     * @param groupKey
     * @return
     */
    public static CacheItem makeSure(final String groupKey) {
        CacheItem item = CACHE.get(groupKey);
        if (null != item) {
            return item;
        }
        CacheItem tmp = new CacheItem(groupKey);
        item = CACHE.putIfAbsent(groupKey, tmp);
        return (null == item) ? tmp : item;
    }
}
